using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;

using SBPweb.Modules.Modularity;
using SBPweb.Presentation.Windows.Forms.Controls;
using System.Runtime.InteropServices;

namespace SBPweb.Modules.WebBrowser
{
	public partial class FavoritesControl : ModalDockingUserControl
	{
		#region Private memebrs

		private IModule mParentModule;
		private int mousePosX = 0;
		private int mousePosY = 0;
		private bool mCloseAfterClickOnFavorite = true;

		#endregion

		#region Public members

		public bool CloseAfterClickOnFavorite
		{
			get { return mCloseAfterClickOnFavorite; }
			set { mCloseAfterClickOnFavorite = value; }
		}

		#endregion

		#region Constructor logic

		public FavoritesControl(IModule parentModule)
			: base(parentModule)
		{
			mParentModule = parentModule;
			InitializeComponent();

			LoadFavourites();
		}

		#endregion

		#region Private helper methods

		private void LoadFavourites()
		{
			string favoritesPath = Environment.GetFolderPath(Environment.SpecialFolder.Favorites);
			tvFavorites.BeginUpdate();
			tvFavorites.Nodes.Clear();
			LoadFavoritesFromFolder(new System.IO.DirectoryInfo(favoritesPath), null);
			LoadFavoritesFromPath(favoritesPath, null);
			tvFavorites.EndUpdate();
			tvFavorites.SelectedNode = null;
			if (tvFavorites.Nodes.Count > 0)
			{
				tvFavorites.SelectedNode = tvFavorites.Nodes[0];
			}
		}

		/// <summary>
		/// Load each sub-folder's favorites.  This method is called recursivley for
		/// each sub-directory.
		/// </summary>
		/// <param name="dirInfo">Directory information for the directory being processed.</param>
		/// <param name="currentNode">The current TreeView Node being processed</param>
		private void LoadFavoritesFromFolder(System.IO.DirectoryInfo dirInfo, TreeNode currentNode)
		{
			System.Windows.Forms.TreeNode objNode;

			foreach (System.IO.DirectoryInfo objDir in dirInfo.GetDirectories())
			{
				if (currentNode == null)
				{
					objNode = tvFavorites.Nodes.Add(objDir.Name, objDir.Name, 2, 1);
				}
				else
				{
					objNode = currentNode.Nodes.Add(objDir.Name, objDir.Name, 2, 1);
				}

				objNode.Tag = objDir.FullName;

				if (objDir.GetDirectories().Length == 0)
				{
					// This node has no further sub-directories
					LoadFavoritesFromPath(objDir.FullName, objNode);
				}
				else
				{
					// Add this folder to the current node and continue
					// processing sub-directories.
					LoadFavoritesFromFolder(objDir, objNode);
					LoadFavoritesFromPath(objDir.FullName, objNode);
				}
			}
		}

		/// <summary>
		/// Loads the favorites from the specified path.
		/// </summary>
		/// <param name="astrPath">The path to read the favorites (URL links)
		/// from.</param>
		/// <param name="currentNode">The TreeView node the favorites should
		/// be placed in.</param>
		private void LoadFavoritesFromPath(string astrPath, TreeNode currentNode)
		{
			string name;
			System.IO.DirectoryInfo objDir = new System.IO.DirectoryInfo(astrPath);

			// Process each URL in the path (URL files end with a ".url" extension
			foreach (System.IO.FileInfo objFile in objDir.GetFiles("*.url"))
			{
				// Set the Text property to the "Friendly" name
				name = Path.GetFileNameWithoutExtension(objFile.Name);

				if (currentNode == null)
				{
					tvFavorites.Nodes.Add(name, name, 0, 0).Tag = IniReadValue("InternetShortcut", "URL", objFile.FullName);
				}
				else
				{
					currentNode.Nodes.Add(name, name, 0, 0).Tag = IniReadValue("InternetShortcut", "URL", objFile.FullName);
				}
			}
		}

		/// <summary>
		/// Reads a data value from the INI file.
		/// </summary>
		/// <param name="section">The INI file section containing the <c>Key</c> value.</PARAM>
		/// Section name
		/// <param name="key">The <c>Key</c> to read the value from.</PARAM>
		/// <param name="path">The path to the INI file being read from.</param>
		/// <returns>a <c>String</c> value containing the INI value.</returns>
		private string IniReadValue(string section, string key, string path)
		{
			StringBuilder temp = new StringBuilder(255);
			int i = GetPrivateProfileString(section, key, "", temp, 255, path);

			return temp.ToString();
		}

		#endregion
		
		#region Events and delegates

		public event FavoritesClickedHandler OnFavoritesClicked;
		public event EventHandler OnClosed;

		public delegate void FavoritesClickedHandler(FavoritesClickedEventArgs ea);

		#endregion

		#region UI event handlers

		private void tvFavorites_Click(object sender, EventArgs e)
		{
			if ((mousePosX != -1) && (mousePosY != -1))
			{
				TreeView objTreeView = (TreeView)sender;
				TreeNode objNode = objTreeView.GetNodeAt(mousePosX, mousePosY);

				if (objNode != null)
				{
					if (objNode.ImageIndex == 0)
					{
						// A URL was clicked
						string _currentURL = (string)objNode.Tag;
						string _currentURLName = (string)objNode.Text;

						// Raise an event notifying the owner that a URL was clicked
						if (OnFavoritesClicked != null)
						{
							OnFavoritesClicked(new FavoritesClickedEventArgs(_currentURL));
						}
						if (mCloseAfterClickOnFavorite && OnClosed != null)
						{
							OnClosed(this, EventArgs.Empty);
						}
					}
				}
			}
		}

		private void tvFavorites_MouseMove(object sender, MouseEventArgs e)
		{
			TreeView objTreeView = (TreeView)sender;
			TreeNode objNode = objTreeView.GetNodeAt(e.X, e.Y);

			if (objNode != null)
			{
				if (objNode.Tag != null)
				{
					// We're over a URL
					objTreeView.Cursor = Cursors.Hand;
				}
				else
				{
					// We're over a folder
					objTreeView.Cursor = Cursors.Default;
				}
			}
			else
			{
				// We're over an empty region in the TreeView
				objTreeView.Cursor = Cursors.Default;
			}
		}

		private void tvFavorites_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			// Only track the mouse button clicks if it was the left button that was
			// clicked
			if (e.Button == System.Windows.Forms.MouseButtons.Left)
			{
				mousePosX = e.X;
				mousePosY = e.Y;
			}
			else
			{
				mousePosX = -1;
				mousePosY = -1;
			}
		}

		private void btnClose_Click(object sender, System.EventArgs e)
		{
			if (OnClosed != null)
			{
				OnClosed(this, EventArgs.Empty);
			}
			this.Hide();
		}

		#endregion

		#region API declarations

		[DllImport("kernel32")]
		private static extern int GetPrivateProfileString(string section,
			string key, string def, StringBuilder retVal,
			int size, string filePath);

		#endregion
	}

	public class FavoritesClickedEventArgs : EventArgs
	{
		#region Private members

		private string mUrl;

		#endregion

		#region Public members

		public string Url
		{
			get
			{
				return mUrl;
			}
		}

		#endregion

		#region Constructor logic

		public FavoritesClickedEventArgs(string url)
		{
			mUrl = url;
		}

		#endregion
	}
}
